#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
#include <unistd.h>
#include <sys/time.h>

long double pi = 0;
int done = 0;
pthread_mutex_t mutexsum;
struct timeval start;

long double iterate(int i) {
    return (4.0f / (2.0f * (long double) i - 1.0f)) * pow(-1.0f, (long double) i + 1.0f);
}

void *pifunc(void *t) {
    int ITERATIONS =  *((int*) t);
    struct timeval end;
    int i;
    long double waarde;
    for(i = 0; i < ITERATIONS && !done; i++) {
        waarde = iterate(i + 1);
        pthread_mutex_lock(&mutexsum);
        pi += waarde;
        pthread_mutex_unlock(&mutexsum);
        gettimeofday(&end,NULL);
        if(end.tv_sec - start.tv_sec > 10) {
            done = 1;
        }
    }
    done = 1;
    pthread_exit(NULL);
}

void *timerfunc(void *t) {
    while(!done) {
        sleep(1);
        pthread_mutex_lock(&mutexsum);
        printf("Pi: %1.20Lf\n", pi);
        pthread_mutex_unlock(&mutexsum);
    }
    pthread_exit(NULL);
}

int main() {
    pthread_t pithread, timerthread;
    pthread_mutex_init(&mutexsum, NULL);
    gettimeofday(&start,NULL);

    int rc;
    int ITER = 1000000000;
    rc = pthread_create(&pithread, NULL, pifunc, (void*) &ITER);
    if (rc) {
        printf("ERROR: return code from pthread_create() is %d\n", rc);
        exit(-1);
    }

    rc = pthread_create(&timerthread, NULL, timerfunc, NULL);
    if (rc) {
        printf("ERROR: return code from pthread_create() is %d\n", rc);
        exit(-1);
    }

    rc = pthread_join(pithread, NULL);
    if(rc) {
        printf("ERROR: return code from pthread_join() is %d\n", rc);
        exit(-1);
    }

    rc = pthread_join(timerthread, NULL);
    if(rc) {
        printf("ERROR: return code from pthread_join() is %d\n", rc);
        exit(-1);
    }
    return 0;
}
